/*---------------------------------------------------------------------------*/
// DisC Decompilation Wizard
// written by
// Satish Kumar S
// satish@miel.mot.com
//
// Copyright 1999-2001 Satish Kumar S
//
// Permission is granted to use this software for research purposes as
// long as this notice stays attached to this software.
/*---------------------------------------------------------------------------*/
#include <assert.h>
#include "InstInfo.h"
#include "Wizard.h"
#include "DisC.h"

extern char Effaddrstr[8][6];
extern char Regstr[2][8][3];
void InstInfo::Clear()
{
  Instr = UNKNOWN;
  operSize1 = operSize2 = 0;
  Operand1 = Operand2 = OPER_UNKNOWN;
  Data11 = Data12 = 0;
  Data21 = Data22 = 0;
}
void InstInfo::SwapOperands()
{
  int o1;
  int t1;
  Word w1;
  Sword s1;
  o1 = operSize1; t1 = Operand1; w1 = Data11; s1 = Data12;
  operSize1 = operSize2; Operand1 = Operand2;
  Data11 = Data21; Data12 = Data22;
  operSize2 = o1; Operand2 = t1; Data21 = w1; Data22 = s1;
}
String InstInfo::GetOperand(int oper,String *Regs,int getName)
{
  String str,tmp,tmp1;
  #define toStr(s) tmp1.Copy(s)
  int val;
  char *vName=0;
  Variable v;
  GetVariable(v,oper);
  switch(v.Operand)
  {
    case IMMEDIATE :
	  str = String((Word)v.Data1);
	  break;
    case REG_DIRECT :
	  if (RegisterVariable(v.Data1))
	    str=GetRegVarName(v.Data1);
	  else str=Regs[v.Data1];
	  break;
    case REG_INDIRECT :
	  tmp="";
	ComForIndexed:
	  int whichReg=-1,whichReg1=-1;
	  switch(v.Data1)
	  {
	    case INDX_BX_SI : whichReg=REG_BX; whichReg1=REG_SI; break;
	    case INDX_BX_DI : whichReg=REG_BX; whichReg1=REG_DI; break;
	    case INDX_BX : whichReg = REG_BX; break;
	    case INDX_SI : whichReg = REG_SI; break;
	    case INDX_DI : whichReg = REG_DI; break;
	    case INDX_BP :
		// for local variables like [BP-02] etc.
		if (getName)
		  vName=LocalVars.GetName(v);
		if (vName) str=vName;
		else { str = toStr("[") + Effaddrstr[v.Data1] + tmp + "]"; }
		break;
	    default: str = toStr("*(") + Effaddrstr[v.Data1] + tmp + ")";
	  }
	  if (whichReg!=-1)
	  {
	    if (RegisterVariable(whichReg))
	    {
	      str=GetRegVarName(whichReg);
	      str = toStr("*(") + str + tmp + ")";
	    }
	    else
	    {
	      str = toStr("*(") + Regs[whichReg];
	      if (whichReg1!=-1) str += toStr(" + ") + Regs[whichReg1];
	      str += tmp + ")";
	    }
	  }
	  break;
    case MEMORY :
	  if (getName) vName=GlobalVars.GetName(v);
	  if (vName) str=vName;
	  else { str = toStr("["); str += v.Data1 ; str+= "]"; }
	  break;
    case INDEXED_BYTE :
	  val = v.Data2;
	  tmp += (val<0)?"-":"+";
	  tmp += (val<0)?(Byte)(256-val):(Byte)val;
	  goto ComForIndexed;
    case INDEXED_WORD :
	  val = v.Data2;
	  tmp += (val<0)?"-":"+";
	  tmp += (val<0)?(Byte)(256-val):(Byte)val;
	  goto ComForIndexed;
  }
  return str;
}
Variable &InstInfo::GetVariable(Variable &t,int whichVar)
{
  if (whichVar==1)
  {
    t.Operand=Operand1;
    t.Data1=Data11;
    t.Data2=Data12;
  }
  else
  {
    t.Operand=Operand2;
    t.Data1=Data21;
    t.Data2=Data22;
  }
  return t;
}
Variable &InstInfo::SetVariable(Variable &t,int whichVar)
{
  if (whichVar==1)
  {
    Operand1=t.Operand;
    Data11=t.Data1;
    Data21=t.Data2;
  }
  else
  {
    Operand2=t.Operand;
    Data21=t.Data1;
    Data22=t.Data2;
  }
  return t;
}
